#!/bin/bash
# KWDB SDK Environment Setup Script
# This script sets up the development environment for KWDB SDK

set -e  # Exit on error

# Color codes for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color

# Helper functions
print_header() {
    echo -e "${BLUE}============================================${NC}"
    echo -e "${BLUE}$1${NC}"
    echo -e "${BLUE}============================================${NC}"
}

print_success() {
    echo -e "${GREEN}✓ $1${NC}"
}

print_error() {
    echo -e "${RED}✗ $1${NC}"
}

print_info() {
    echo -e "${YELLOW}ℹ $1${NC}"
}

# Detect OS
if [[ "$OSTYPE" == "linux-gnu"* ]]; then
    OS="linux"
elif [[ "$OSTYPE" == "darwin"* ]]; then
    OS="macos"
else
    print_error "Unsupported operating system: $OSTYPE"
    exit 1
fi

print_header "KWDB SDK Environment Setup"
echo "Detected OS: $OS"
echo ""

# Function to check if a command exists
command_exists() {
    command -v "$1" >/dev/null 2>&1
}

# Function to install packages on Linux
install_linux_packages() {
    print_info "Updating package lists..."
    sudo apt-get update

    print_info "Installing required packages..."
    sudo apt-get install -y \
        build-essential \
        cmake \
        git \
        curl \
        wget \
        libssl-dev \
        libprotobuf-dev \
        protobuf-compiler \
        protobuf-compiler-grpc \
        libgrpc++-dev \
        libgrpc-dev \
        libcurl4-openssl-dev \
        zlib1g-dev \
        libpq-dev \
        postgresql-client \
        openjdk-11-jdk \
        python3 \
        python3-pip \
        pkg-config
}

# Function to install packages on macOS
install_macos_packages() {
    if ! command_exists brew; then
        print_info "Installing Homebrew..."
        /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
    fi

    print_info "Installing required packages..."
    brew install \
        cmake \
        git \
        curl \
        wget \
        protobuf \
        grpc \
        openssl \
        zlib \
        postgresql \
        pkg-config \
        openjdk@11 \
        python3
}

# Step 1: Install system dependencies
print_header "Step 1: Installing System Dependencies"

if [[ "$OS" == "linux" ]]; then
    install_linux_packages
elif [[ "$OS" == "macos" ]]; then
    install_macos_packages
fi

print_success "System dependencies installed"

# Step 2: Check and install CMake (minimum version 3.10)
print_header "Step 2: Verifying CMake Installation"

if command_exists cmake; then
    CMAKE_VERSION=$(cmake --version | head -n1 | cut -d' ' -f3)
    print_success "CMake $CMAKE_VERSION found"

    # Check minimum version
    REQUIRED_VERSION="3.10.0"
    if [ "$(printf '%s\n' "$REQUIRED_VERSION" "$CMAKE_VERSION" | sort -V | head -n1)" != "$REQUIRED_VERSION" ]; then
        print_error "CMake version $CMAKE_VERSION is too old. Minimum required: $REQUIRED_VERSION"
        exit 1
    fi
else
    print_error "CMake not found after installation"
    exit 1
fi

# Step 3: Check Java installation
print_header "Step 3: Verifying Java Installation"

if command_exists java; then
    JAVA_VERSION=$(java -version 2>&1 | head -n1)
    print_success "Java found: $JAVA_VERSION"

    # Extract major version number
    JAVA_MAJOR=$(echo "$JAVA_VERSION" | grep -oE '"[0-9]+' | grep -oE '[0-9]+' | head -1)
    if [ -z "$JAVA_MAJOR" ]; then
        # For older Java versions (1.8 format)
        JAVA_MAJOR=$(echo "$JAVA_VERSION" | grep -oE '1\.[0-9]+' | cut -d. -f2)
    fi

    # Check if Java version is at least 11
    if [ "$JAVA_MAJOR" -ge 11 ]; then
        print_success "Java version $JAVA_MAJOR meets minimum requirement (11+)"
    else
        print_error "Java version $JAVA_MAJOR is too old. Minimum required: Java 11"
        print_info "Please install Java 11 or newer"
        exit 1
    fi
else
    print_error "Java not found"
    exit 1
fi

# Step 4: Setup Gradle wrapper
print_header "Step 4: Setting up Gradle"

PROJECT_ROOT="$(cd "$(dirname "$0")" && pwd)"
cd "$PROJECT_ROOT/sdk-java"

if [ ! -f "gradlew" ]; then
    print_info "Gradle wrapper not found, creating..."
    # Download gradle wrapper (8.5 for Java 11+ support)
    wget https://services.gradle.org/distributions/gradle-8.5-bin.zip
    unzip -q gradle-8.5-bin.zip
    gradle-8.5/bin/gradle wrapper
    rm -rf gradle-8.5*
    print_success "Gradle wrapper created"
else
    print_success "Gradle wrapper already exists"
fi

# Make gradlew executable
chmod +x gradlew
cd "$PROJECT_ROOT"

# Step 5: Install/Setup Database (using CockroachDB as KWDB substitute)
print_header "Step 5: Database Setup"

print_info "For testing, we'll use CockroachDB as a KWDB substitute..."
print_info "Installing CockroachDB..."

if [[ "$OS" == "linux" ]]; then
    # Download CockroachDB
    wget -qO- https://binaries.cockroachdb.com/cockroach-latest.linux-amd64.tgz | tar xvz
    sudo cp cockroach-*/cockroach /usr/local/bin/ 2>/dev/null || true
    rm -rf cockroach-*
elif [[ "$OS" == "macos" ]]; then
    brew install cockroachdb/tap/cockroach
fi

if command_exists cockroach; then
    print_success "CockroachDB installed successfully"
    print_info "To start CockroachDB: cockroach start-single-node --insecure --background"
else
    print_error "Failed to install CockroachDB"
fi

# Step 6: Build the project
print_header "Step 6: Building the Project"

print_info "Building C++ components..."
cd "$PROJECT_ROOT"

# Clean any existing generated protobuf files
print_info "Cleaning old generated protobuf files..."
rm -rf generated/ 2>/dev/null || true
rm -rf build/ 2>/dev/null || true

mkdir -p build
cd build

# Explicitly use system protoc to avoid version conflicts
print_info "Configuring build with system protoc..."
cmake -DPROTOC=/usr/bin/protoc -DGRPC_CPP_PLUGIN=/usr/bin/grpc_cpp_plugin ..
make -j$(nproc 2>/dev/null || sysctl -n hw.ncpu)
cd "$PROJECT_ROOT"
print_success "C++ build completed"

print_info "Building Java SDK..."
cd "$PROJECT_ROOT/sdk-java"
./gradlew clean build -x test
cd "$PROJECT_ROOT"
print_success "Java build completed"

# Step 7: Verify installation
print_header "Step 7: Installation Verification"

echo "Checking built binaries..."

# Check C++ binaries
if [ -f "$PROJECT_ROOT/server/ingestd/ingestd" ]; then
    print_success "IngestD server binary found"
else
    print_error "IngestD server binary not found"
fi

if [ -f "$PROJECT_ROOT/test/cpp/test_single_write" ]; then
    print_success "C++ test binaries found"
else
    print_error "C++ test binaries not found"
fi

# Check Java build
if [ -d "$PROJECT_ROOT/sdk-java/build/libs" ]; then
    print_success "Java SDK JAR files built"
else
    print_error "Java SDK JAR files not found"
fi

# Step 8: Environment variables
print_header "Step 8: Setting Environment Variables"

ENV_FILE="$HOME/.kwdb_sdk_env"
cat > "$ENV_FILE" << EOF
# KWDB SDK Environment Variables
export KWDB_SDK_ROOT="$PROJECT_ROOT"
export KWDB_BUILD_DIR="$PROJECT_ROOT/build"
export KWDB_INGESTD_PORT=9090
export KWDB_INGESTD_UDS="/tmp/kwdb-ingestd.sock"
EOF

print_info "Environment variables saved to $ENV_FILE"
print_info "To load them: source $ENV_FILE"

# Add to bashrc/zshrc
if [ -f "$HOME/.bashrc" ]; then
    if ! grep -q "kwdb_sdk_env" "$HOME/.bashrc"; then
        echo "[ -f $ENV_FILE ] && source $ENV_FILE" >> "$HOME/.bashrc"
        print_success "Added to .bashrc"
    fi
fi

if [ -f "$HOME/.zshrc" ]; then
    if ! grep -q "kwdb_sdk_env" "$HOME/.zshrc"; then
        echo "[ -f $ENV_FILE ] && source $ENV_FILE" >> "$HOME/.zshrc"
        print_success "Added to .zshrc"
    fi
fi

# Summary
print_header "Setup Complete!"
echo ""
echo "Installation Summary:"
echo "  ✓ System dependencies installed"
echo "  ✓ CMake verified (minimum 3.10)"
echo "  ✓ Java environment configured"
echo "  ✓ Gradle wrapper set up"
echo "  ✓ Database tools installed"
echo "  ✓ Project built successfully"
echo "  ✓ Environment variables configured"
echo ""
echo "Next Steps:"
echo "  1. Source environment: source $ENV_FILE"
echo "  2. Start IngestD server: $PROJECT_ROOT/server/ingestd/ingestd"
echo "  3. Run demo: $PROJECT_ROOT/demo_full_system.sh"
echo ""
print_success "Environment setup completed successfully!"